interface ApiOptions {
  url: string
  data?: any
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE'
  domain?: string
  noAuth?: boolean
}

interface ApiResponse<T = any> {
  returnCode: string
  returnMessage: string
  data: T
}

const createApi = (defaultHeader: Record<string, string> = {}) => {
  // 从环境变量读取 baseUrl
  const apiBaseUrl = import.meta.env.API_BASE_URL

  const api = <T = any>(opts: ApiOptions): Promise<ApiResponse<T>> => {
    // 监听网络链接
    uni.onNetworkStatusChange((res) => {
      if (!res.isConnected) {
        uni.showToast({
          title: '网络连接不可用！',
          icon: 'none'
        })
      }
    })

    // 设置请求 method 和 baseUrl
    opts.method = opts.method || 'GET'
    const url = (opts.domain || apiBaseUrl) + opts.url

    // 获取 token 和鉴权信息
    const token = uni.getStorageSync('token') || ''
    // const authorize = uni.getStorageSync('Authorization') || ''

    // 设置请求头
    const header: Record<string, string> = {
      ...defaultHeader,
      Authorization: token,
      'Content-Type': 'application/json; charset=UTF-8'
    }

    // 是否取消鉴权
    if (opts.noAuth) {
      delete header.Authorization
    }

    return new Promise((resolve, reject) => {
      uni.request({
        url,
        data: opts.data,
        method: opts.method as any,
        header: header,
        success: (res: any) => {
          if (res.statusCode === 200) {
            if (res.data.returnCode === '200') {
              resolve(res.data)
            } else if (res.data.returnCode === '401') {
              uni.showModal({
                title: '提示',
                content: '登录过期，请重新登录',
                success: (res: any) => {
                  if (res.confirm) {
                    uni.redirectTo({
                      url: '/pages/login/index'
                    })
                    uni.clearStorageSync()
                  } else if (res.cancel) {
                    uni.switchTab({
                      url: '/pages/work/index'
                    })
                  }
                }
              })
              resolve(res.data)
            } else {
              uni.showToast({
                title: res.data.returnMessage || '请求失败',
                icon: 'none',
                duration: 1500
              })
              reject(res.data)
            }
          } else {
            uni.showToast({
              title: `网络错误: ${res.statusCode}`,
              icon: 'none',
              duration: 1500
            })
            reject(res)
          }
        },
        fail: (error) => {
          console.log('请求失败,请稍候重试', error)
          uni.hideLoading()
          uni.showToast({
            title: '请求失败，请稍后重试',
            icon: 'none',
            duration: 1500
          })
          reject(error)
        }
      })
    })
  }

  const get = <T = any>(options: ApiOptions) => {
    options.method = 'GET'
    return api<T>(options)
  }

  const post = <T = any>(options: ApiOptions) => {
    options.method = 'POST'
    return api<T>(options)
  }

  const put = <T = any>(options: ApiOptions) => {
    options.method = 'PUT'
    return api<T>(options)
  }

  const del = <T = any>(options: ApiOptions) => {
    options.method = 'DELETE'
    return api<T>(options)
  }

  return { get, post, put, del }
}

export default createApi
